import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
import 'package:yuellyfactory/eventbus/EventRefreshPart.dart';
import 'package:yuellyfactory/views/dto/PriceMaterial.dart';
import 'package:yuellyfactory/views/dto/PricePart.dart';
import 'package:yuellyfactory/views/purchase/MaterialItemView.dart';

import '../../components/NoScrollbarBehavior.dart';
import '../../eventbus/EventBusUtil.dart';
import '../../eventbus/EventRefreshMaterial.dart';
import '../../util/BaseRequest.dart';
import '../../util/ColorUtil.dart';
import '../../util/ViewUtil.dart';
import '../../util/XNumberTextInputFormatter.dart';
import 'package:yuellyfactory/views/dto/PriceParm.dart';
import 'package:yuellyfactory/util/MathUtil.dart';
import 'dart:convert';
import '../dto/PriceRule.dart';

class PurchaseMaterial extends StatefulWidget {
  const PurchaseMaterial({super.key});

  @override
  State<PurchaseMaterial> createState() => _PurchaseMaterialState();
}

class _PurchaseMaterialState extends State<PurchaseMaterial> {

  StreamSubscription? streamSubscription;

  StreamSubscription? partStreamSubscription;

  PricePart pricePart=PricePart();
  List<PricePart> configData=[];
  Map<String,bool> showMaps={};

  //所有的值对应ID
  Map allValue={};
  final TextEditingController _countController = TextEditingController();
 // final TextEditingController _prifitController = TextEditingController();
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _countController.text="1";
    streamSubscription = eventBus.on<EvetnRefreshMaterial>().listen((event) {
      if(pricePart!=null&&event.pricePart.id!=pricePart!.id){
        _countController.text="1";
      }
      pricePart=event.pricePart;

      if(mounted){
        setState(() {

        });
      }

      getData();
    });

    partStreamSubscription = eventBus.on<EventRefreshPart>().listen((event) {
      getData();
    });

  }

  @override
  void dispose() {
    if (streamSubscription != null) {
      streamSubscription!.cancel();
    }
    if (partStreamSubscription != null) {
      partStreamSubscription!.cancel();
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Card( color: Colors.white,

          child: Container(
              width: double.infinity,
              padding: const EdgeInsets.all(5.0),
              margin: EdgeInsets.only(left: ViewUtil.screenWidth(10),),
              child:
              Wrap(
                direction: Axis.horizontal,
                spacing: 2,
                // 垂直方向（换行后）的间距
                runSpacing: 10,
                // 子组件对齐方式（水平方向）
                alignment: WrapAlignment.start, // 靠左对齐（默认）
                // 换行后的行对齐方式（垂直方向）
                runAlignment: WrapAlignment.start,
                crossAxisAlignment: WrapCrossAlignment.center,
                children: [

                  Text(
                    pricePart==null?"":pricePart!.name,
                    style: TextStyle(fontSize: ViewUtil.fontSize(28)),
                  ),
                  const SizedBox(width: 20),
                  //小数点
                  SizedBox(width: 120,
                    child:
                    ShadInput(
                      placeholder: const Text("请输入数量"),
                      controller: _countController,
                      prefix: const Text("数量："),
                      onChanged: (value){
                        getTotalPrice();
                        setState(() {

                        });
                      },
                      keyboardType: TextInputType.numberWithOptions(decimal: true),
                      inputFormatters: [
                        FilteringTextInputFormatter.allow(RegExp("[0-9.]")),
                        XNumberTextInputFormatter(
                            maxIntegerLength: null,
                            maxDecimalLength: 2,
                            isAllowDecimal: true),
                      ],
                    ),),

                  const SizedBox(width: 16),
                  Text(
                    "总材料价:${pricePart==null?"0":MathUtil.formatDouble(pricePart!.totalPrice, 2)}元",
                    style: TextStyle(fontSize: ViewUtil.fontSize(18)),
                  ),
                  const SizedBox(width: 10),

                  Text(
                    "出厂价:${pricePart==null?"0":MathUtil.formatDouble(countProfit(pricePart!.totalPrice), 2)}元",
                    style: TextStyle(fontSize: ViewUtil.fontSize(18)),
                  ),
                  const SizedBox(width: 10),

                  Text(
                    "经销商价:",
                    style: TextStyle(fontSize: ViewUtil.fontSize(18)),
                  ),
                  Visibility(
                      visible: getDiscount()>0,
                      child: Text("${pricePart==null?"0":MathUtil.formatDouble(countAgentPrice(), 2)}元",style:TextStyle(fontSize: ViewUtil.fontSize(18),decoration: TextDecoration.lineThrough,),)),

                  Text("${MathUtil.formatDouble(countAgentPrice()*(100-getDiscount())/100, 2)}元",style:TextStyle(fontSize: ViewUtil.fontSize(18),) ,),
                  const SizedBox(width: 10),
                  Text(
                    "终端价:",
                    style: TextStyle(fontSize: ViewUtil.fontSize(18)),
                  ),

                  Visibility(
                      visible: getDiscount()>0,
                      child: Text("${pricePart==null?"0":MathUtil.formatDouble(countRetailPrice(), 2)}元",style:TextStyle(fontSize: ViewUtil.fontSize(18),decoration: TextDecoration.lineThrough,),)),

                  Text("${MathUtil.formatDouble(countRetailPrice()*(100-getDiscount())/100, 2)}元",style:TextStyle(fontSize: ViewUtil.fontSize(18),) ,),

                  const SizedBox(width: 10),
                ],
              )),
        ),
        Expanded(
          child: Card( color: Colors.white,
            child:
            ScrollConfiguration(
              behavior: NoScrollbarBehavior(),
              child: SingleChildScrollView(
                child:
                Padding(
                  padding: const EdgeInsets.all(5.0),
                  child:
                  Column(
                    children: getPartsWidget(),
                  )
                  ,
                ),),
            ),

          ),
        ),
      ],
    );
  }


   countProfit(double price){

    if(price==0){
      pricePart.exFactoryPrice=price;
      return price;
    }


    var profit=pricePart.grossMargin;
    if(profit.isEmpty){
      pricePart.exFactoryPrice=price;
      return price;
    }

    double dValue=double.parse(profit);
    if(dValue<0||dValue>100){
      pricePart.exFactoryPrice=price;
      return price;
    }
    var p=price/(1-dValue/100.0);
    pricePart.exFactoryPrice=p;
    return p;
  }

  countAgentPrice(){
    if(pricePart.exFactoryPrice==0){
      pricePart.agentPrice=pricePart.totalPrice;
      return pricePart.totalPrice;
    }
    var profit=pricePart.profitMargin;
    if(profit.isEmpty){
      pricePart.agentPrice=pricePart.totalPrice;
      return pricePart.totalPrice;
    }

    double dValue=double.parse(profit);
    if(dValue<0||dValue>100){
      pricePart.agentPrice=pricePart.totalPrice;
      return pricePart.totalPrice;
    }
    var p=pricePart.exFactoryPrice*(1+dValue/100.0);
    pricePart.agentPrice=p;
    return p;
  }

  countRetailPrice(){
    if(pricePart.agentPrice==0){
      pricePart.retailPrice=pricePart.totalPrice;
      return pricePart.totalPrice;
    }
    var profit=pricePart.retailRatio;
    if(profit.isEmpty){
      pricePart.retailPrice=pricePart.totalPrice;
      return pricePart.totalPrice;
    }

    double dValue=double.parse(profit);
    if(dValue<0||dValue>100){
      pricePart.retailPrice=pricePart.totalPrice;
      return pricePart.totalPrice;
    }
    var p=pricePart.agentPrice*(1+dValue/100.0);
    pricePart.retailPrice=p;
    return p;
  }


  getDiscount(){
    String discount= pricePart.discount;
    var count=_countController.text;
    if(count.isEmpty){
      count="0";
    }
    double inputCount=double.parse(count);
    num discountValue=0;
    if(discount.isNotEmpty) {
      List discountList = jsonDecode(discount);

      for (var item in discountList) {
        int max = int.tryParse(item["max"] ?? "") ?? 0;
        num? value = MathUtil.parseNumValue(item["value"]);
        if (inputCount >= max) {
          discountValue = value ?? 0;
          break;
        }
      }
    }
    return discountValue;
  }

  getTotalPrice(){
    var count=_countController.text;
    if(count.isEmpty){
      count="0";
    }
    double inputCount=double.parse(count);
    double totalPrice=0;
    for(PricePart partData in configData){
      totalPrice=totalPrice+partData.price;
    }
    totalPrice=inputCount*totalPrice;
    debugPrint('总价$totalPrice');

    //计算折扣

   // String discount= pricePart.discount;
   // if(discount.isNotEmpty){
   //  List discountList= jsonDecode(discount);
   //  num? discountValue;
   //  for(var item in discountList){
   //    int max = int.tryParse(item["max"] ?? "") ?? 0;
   //    num? value=MathUtil.parseNumValue(item["value"]);
   //    if(inputCount>=max){
   //      discountValue=value;
   //      break;
   //    }
   //  }
   //  if(discountValue!=null){
   //    debugPrint('折扣$discountValue');
   //    totalPrice=totalPrice*(100-discountValue)/100;
   //  }
   // }


   if(pricePart!=null){
     pricePart!.totalPrice=totalPrice;
   }
  }

  List<Widget> getPartsWidget(){
    List<Widget> list=[];
    for(PricePart partData in configData){
      list.add(materialItem(partData));
    }

    return list;
  }

  Widget materialItem(PricePart partData){

    return MaterialItemView(context,(){
      //计算总价


    },this,showMaps).getPartView(partData);
  }


  void getData(){
    var parm={
      "modelId":pricePart!.id
    };
    BaseRequest.postHttp('price/getproductconfig',parameters: parm, canTip: true , context: context, onSuccess: (data){
      bool result = BaseRequest.chekResponse(data, true);
      if (result) {
        dynamic datas = data["data"];
        List<PricePart> allModel = [];
        allValue={};
        for (var i = 0; i < datas.length; i++) {
          var item = datas[i];
          var part = PricePart.fromJson(item);
          countPrice(part);
          allModel.add(part);
        }
        configData=allModel;
        getTotalPrice();

        setState(() {

        });

      }
    }, onError: (error){

    });
  }


  getRuleValue(var rule,Map allValue){
    var ruleStr="";
    if(rule.isNotEmpty){
      List<dynamic> list = json.decode(rule);
      for(var item in list){
        PriceRule rule=PriceRule.fromJson(item);
        if(rule.handle==0){
          ruleStr="$ruleStr${rule.value}";
        }else{
          if(allValue.containsKey(rule.value)){
            ruleStr="$ruleStr${allValue[rule.value]}";
          }else{
            return 0;
          }
        }
      }
    }
    return MathUtil.countExpression(ruleStr);
  }



  getMaterialRuleValue(var rule,var materialId,Map allValue){
    var ruleStr="";
    if(rule.isNotEmpty){
      List<dynamic> list = json.decode(rule);
      for(var item in list){
        PriceRule rule=PriceRule.fromJson(item);
        if(rule.handle==0){
          ruleStr="$ruleStr${rule.value}";
        }else{
          if(allValue.containsKey(materialId+"_"+rule.value)){
            var value=allValue[materialId+"_"+rule.value];
            if(value.toString().isEmpty){
              value="0";
            }
            ruleStr="$ruleStr$value";
          }

          else if(allValue.containsKey(rule.value)){
            var value=allValue[rule.value];
            if(value.toString().isEmpty){
              value="0";
            }
            ruleStr="$ruleStr$value";
          }else{
            ruleStr="${ruleStr}0";
          }
        }
      }
    }
    return MathUtil.countExpression(ruleStr);
  }

  void countPrice(PricePart partData){
    //先计算全局参数

    //先计算一遍全局参数
    for(PriceParm parm in partData.parmList){
      if(parm.handle==0){
        allValue[parm.id]=parm.value;
      }
    }
    for(PriceParm parm in partData.parmList){
      if(parm.handle==1){
        var value=getRuleValue(parm.rule, allValue);
        allValue[parm.id]=value;
      }
    }
    //计算每一个材料参数
    for(PricePart material in partData.materialList){
      //这是品牌一级
      countBrandPrice(material);
    }

    double totalPrice=0;
      //品牌
      for(PricePart brand in partData.materialList){
        //系列
         for(PricePart serial in brand.materialList){
           for(PricePart part in serial.materialList){
             //公式以及材料列表、参数都配置，才生效
             if(part.childMaterialList.isNotEmpty&&part.childMaterialList.isNotEmpty&&part.materialRule.isNotEmpty){
                double partPrice=0;
                for(PriceMaterial material in part.childMaterialList){
                    var value=getMaterialRuleValue(part.materialRule, material.id, allValue);
                    material.price=double.parse('$value');
                    partPrice+=material.price;
                }
                part.price=partPrice;
                part.totalPrice=part.count*part.price;
                totalPrice=totalPrice+part.totalPrice;
             }else{
               //没有子数据的时候
                if(part.rule.isNotEmpty&part.parmList.isNotEmpty){
                  var rule=part.rule;
                  var value=getRuleValue(rule, allValue);
                  part.price=double.parse('$value');
                  part.totalPrice=part.count*part.price;
                  totalPrice=totalPrice+part.totalPrice;
                }else{
                  //只体现单价的时候
                  part.price=part.dPrice;
                  part.totalPrice=part.price*part.count;
                  totalPrice=totalPrice+part.totalPrice;
                }
             }


           }


      }


    }
    partData.price=totalPrice;
  }

  void countBrandPrice(PricePart partData){
    for(PricePart material in partData.materialList){
      countSerialPrice(material);
    }
  }

  void countSerialPrice(PricePart partData){
    for(PricePart material in partData.materialList){
      countPartPrice(material);
    }
  }

  countPartPrice(PricePart partData){
      //先判断是否有子级数据，有的话，则直接用
    if(partData.childMaterialList.isNotEmpty&&partData.childParmList.isNotEmpty){
      for(PriceParm parm in partData.childParmList){
         for(PriceMaterial material in partData.childMaterialList){
           if(parm.handle==0){
             allValue["${material.id}_${parm.id}"]=getParmValue(parm.id,material.data);
           }else{
             var rule=getMaterialUniqueRule(parm, material);
             var value=getMaterialRuleValue(rule,material.id, allValue);
             allValue["${material.id}_${parm.id}"]=value;
             List datas=json.decode(material.data);
             bool hasAdd=false;
             for(var item in datas) {
               var id = item["id"];
               if(id==parm.id){
                 item["value"]=value.toString();
                 hasAdd=true;
                 break;
               }
             }
             if(!hasAdd){
               datas.add({"id":parm.id,"value":value.toString()});
             }

             material.data=json.encode(datas);
           }
         }
      }
    }else{
      var parmList= partData.parmList;
      for(PriceParm parm in parmList){
        if(parm.handle==0){
          allValue[parm.id]=parm.value;
        }
      }
      for(PriceParm parm in parmList){
        if(parm.handle==1){
          var value=getRuleValue(parm.rule, allValue);
          allValue[parm.id]=value;
        }
      }
    }
  }


  getMaterialUniqueRule(PriceParm parm ,PriceMaterial material){
    var uniqueRule="";
    var data=material.data;
    if(data==null||data.length==0)return parm.rule;
    List datas=json.decode(data);
    for(var item in datas){
      var id=item["id"];
      if(id==parm.id){
        var rule=item["rule"];
        if(rule!=null&&rule.toString().isNotEmpty){
          uniqueRule=rule;
        }
        break;
      }
    }

    if(uniqueRule.isNotEmpty){
      return uniqueRule;
    }else{
      return parm.rule;
    }
  }

  getParmValue(String id,var data){
    if(data==null||data.length==0)return "";
    List datas=json.decode(data);
    var values={};
    for(var item in datas){
      values[item["id"]]=item["value"];
    }

    String value="";
    if(values.containsKey(id)){
      value=values[id].toString();
    }
    if(value.isEmpty){
      value="0";
    }
    return value;
  }

}
